package l1j.server.server.datatables;

import static l1j.server.server.model.skill.L1SkillId.AWAKEN_ANTHARAS;
import static l1j.server.server.model.skill.L1SkillId.AWAKEN_FAFURION;
import static l1j.server.server.model.skill.L1SkillId.AWAKEN_VALAKAS;
import static l1j.server.server.model.skill.L1SkillId.BLOODLUST;
import static l1j.server.server.model.skill.L1SkillId.DECAY_POTION;
import static l1j.server.server.model.skill.L1SkillId.ENTANGLE;
import static l1j.server.server.model.skill.L1SkillId.GREATER_HASTE;
import static l1j.server.server.model.skill.L1SkillId.HASTE;
import static l1j.server.server.model.skill.L1SkillId.HOLY_WALK;
import static l1j.server.server.model.skill.L1SkillId.MASS_SLOW;
import static l1j.server.server.model.skill.L1SkillId.MOVING_ACCELERATION;
import static l1j.server.server.model.skill.L1SkillId.POLLUTE_WATER;
import static l1j.server.server.model.skill.L1SkillId.SLOW;
import static l1j.server.server.model.skill.L1SkillId.STATUS_BRAVE;
import static l1j.server.server.model.skill.L1SkillId.STATUS_BRAVE2;
import static l1j.server.server.model.skill.L1SkillId.STATUS_ELFBRAVE;
import static l1j.server.server.model.skill.L1SkillId.STATUS_HASTE;
import static l1j.server.server.model.skill.L1SkillId.STATUS_THIRD_SPEED;
import static l1j.server.server.model.skill.L1SkillId.WIND_WALK;
import static l1j.server.server.model.skill.L1SkillId.IE_MR;
import static l1j.server.server.model.skill.L1SkillId.IE_DMG;
import static l1j.server.server.model.skill.L1SkillId.IE_AC;
import static l1j.server.server.model.skill.L1SkillId.IE_EXP;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Map;
import java.util.Random;
import java.util.logging.Level;
import java.util.logging.Logger;

import l1j.server.L1DatabaseFactory;
import l1j.server.server.model.L1PolyMorph;
import l1j.server.server.model.Instance.L1PcInstance;
import l1j.server.server.serverpackets.S_Liquor;
import l1j.server.server.serverpackets.S_OwnCharStatus;
import l1j.server.server.serverpackets.S_SPMR;
import l1j.server.server.serverpackets.S_ServerMessage;
import l1j.server.server.serverpackets.S_SkillBrave;
import l1j.server.server.serverpackets.S_SkillHaste;
import l1j.server.server.serverpackets.S_SkillSound;
import l1j.server.server.utils.SQLUtil;
import l1j.server.server.utils.collections.Maps;

public class ItemExtendTable {
	private static Logger _log = Logger.getLogger(ItemExtendTable.class
			.getName());
	private static ItemExtendTable _instance = new ItemExtendTable();

	public static ItemExtendTable getInstance() {
		return _instance;
	}

	private ItemExtendTable() {
		Connection con = null;
		PreparedStatement pstm = null;
		ResultSet rs = null;
		try {

			con = L1DatabaseFactory.getInstance().getConnection();
			pstm = con.prepareStatement("SELECT * FROM x_item_extend");
			rs = pstm.executeQuery();
			while (rs.next()) {
				ItemExtend ie = new ItemExtend();
				ie.hp = rs.getInt("hp");
				ie.mp = rs.getInt("mp");
				ie.gfxId = rs.getInt("gfxId");
				ie.speed_one = rs.getInt("speed_one");
				ie.speed_two = rs.getInt("speed_two");
				ie.speed_three = rs.getInt("speed_three");
				ie.exp_rate = rs.getInt("exp_rate");
				ie.exp_time = rs.getInt("exp_time");
				ie.poly_id = rs.getInt("poly_id");
				ie.poly_time = rs.getInt("poly_time");
				ie.mr = rs.getInt("mr");
				ie.mr_time = rs.getInt("mr_time");
				ie.dmg = rs.getInt("dmg");
				ie.dmg_time = rs.getInt("dmg_time");
				ie.ac = rs.getInt("ac");
				ie.ac_time = rs.getInt("ac_time");
				_items.put(rs.getInt("item_id"), ie);
			}
		} catch (SQLException e) {
			_log.log(Level.SEVERE, e.getLocalizedMessage(), e);
		} finally {
			SQLUtil.close(rs);
			SQLUtil.close(pstm);
			SQLUtil.close(con);
		}
	}

	private Map<Integer, ItemExtend> _items = Maps.newMap();

	public boolean useItem(L1PcInstance pc, int itemId) {
		if (_items.containsKey(itemId)) {
			if (pc.hasSkillEffect(DECAY_POTION)) { // 藥水霜化術狀態
				pc.sendPackets(new S_ServerMessage(698)); // 喉嚨灼熱，無法喝東西。
				return true;
			}
			ItemExtend ie = _items.get(itemId);
			if (pc.getInventory().consumeItem(itemId, 1)) {
				ie.gfx(pc);
				ie.heal(pc);
				ie.speed(pc);
				ie.mrAcDmg(pc);
				ie.poly(pc);
			}
			return true;
		}
		return false;
	}

	class ItemExtend {
		int hp;
		int mp;
		int gfxId;
		int speed_one;
		int speed_two;
		int speed_three;
		int exp_rate;
		int exp_time;
		int poly_id;
		int poly_time;
		int mr;
		int mr_time;
		int dmg;
		int dmg_time;
		int ac;
		int ac_time;

		void heal(L1PcInstance pc) {
			if (hp > 0) {
				int healHp = hp;
				healHp *= ((new Random()).nextGaussian() / 5.0D) + 1.0D;
				if (pc.hasSkillEffect(POLLUTE_WATER)) { // 汙濁之水 - 效果減半
					healHp /= 2;
				}
				pc.setCurrentHp(pc.getCurrentHp() + healHp);
			}
			if (mp > 0) {
				int healMp = mp;
				healMp *= ((new Random()).nextGaussian() / 5.0D) + 1.0D;
				pc.setCurrentMp(pc.getCurrentMp() + healMp);
			}
		}

		void speed(L1PcInstance pc) {
			if (speed_one > 0) {
				if (pc.getHasteItemEquipped() > 0) {
					return;
				}
				// 刪除重複的加速技能
				if (pc.hasSkillEffect(HASTE)) {
					pc.killSkillEffectTimer(HASTE);
					pc.sendPackets(new S_SkillHaste(pc.getId(), 0, 0));
					pc.broadcastPacket(new S_SkillHaste(pc.getId(), 0, 0));
					pc.setMoveSpeed(0);
				} else if (pc.hasSkillEffect(GREATER_HASTE)) {
					pc.killSkillEffectTimer(GREATER_HASTE);
					pc.sendPackets(new S_SkillHaste(pc.getId(), 0, 0));
					pc.broadcastPacket(new S_SkillHaste(pc.getId(), 0, 0));
					pc.setMoveSpeed(0);
				} else if (pc.hasSkillEffect(STATUS_HASTE)) {
					pc.killSkillEffectTimer(STATUS_HASTE);
					pc.sendPackets(new S_SkillHaste(pc.getId(), 0, 0));
					pc.broadcastPacket(new S_SkillHaste(pc.getId(), 0, 0));
					pc.setMoveSpeed(0);
				}
				// 處理緩速的情況
				if (pc.hasSkillEffect(SLOW)) { // スロー
					pc.killSkillEffectTimer(SLOW);
					pc.sendPackets(new S_SkillHaste(pc.getId(), 0, 0));
					pc.broadcastPacket(new S_SkillHaste(pc.getId(), 0, 0));
				} else if (pc.hasSkillEffect(MASS_SLOW)) { // マス スロー
					pc.killSkillEffectTimer(MASS_SLOW);
					pc.sendPackets(new S_SkillHaste(pc.getId(), 0, 0));
					pc.broadcastPacket(new S_SkillHaste(pc.getId(), 0, 0));
				} else if (pc.hasSkillEffect(ENTANGLE)) { // エンタングル
					pc.killSkillEffectTimer(ENTANGLE);
					pc.sendPackets(new S_SkillHaste(pc.getId(), 0, 0));
					pc.broadcastPacket(new S_SkillHaste(pc.getId(), 0, 0));
				} else {
					pc.sendPackets(new S_SkillHaste(pc.getId(), 1, speed_one));
					pc.broadcastPacket(new S_SkillHaste(pc.getId(), 1, 0));
					pc.setMoveSpeed(1);
					pc.setSkillEffect(STATUS_HASTE, speed_one * 1000);
				}
			}

			if (speed_two > 0) {
				// 消除重複狀態
				if (pc.hasSkillEffect(STATUS_BRAVE)) { // 勇敢藥水類 1.33倍
					pc.killSkillEffectTimer(STATUS_BRAVE);
				}
				if (pc.hasSkillEffect(STATUS_ELFBRAVE)) { // 精靈餅乾 1.15倍
					pc.killSkillEffectTimer(STATUS_ELFBRAVE);
				}
				if (pc.hasSkillEffect(HOLY_WALK)) { // 神聖疾走 移速1.33倍
					pc.killSkillEffectTimer(HOLY_WALK);
				}
				if (pc.hasSkillEffect(MOVING_ACCELERATION)) { // 行走加速 移速1.33倍
					pc.killSkillEffectTimer(MOVING_ACCELERATION);
				}
				if (pc.hasSkillEffect(WIND_WALK)) { // 風之疾走 移速1.33倍
					pc.killSkillEffectTimer(WIND_WALK);
				}
				if (pc.hasSkillEffect(BLOODLUST)) { // 血之渴望 攻速1.33倍
					pc.killSkillEffectTimer(BLOODLUST);
				}
				if (pc.hasSkillEffect(STATUS_BRAVE2)) { // 超級加速 2.66倍
					pc.killSkillEffectTimer(STATUS_BRAVE2);
				}
				// 給予狀態 && 效果
				pc.setSkillEffect(STATUS_BRAVE, speed_two * 1000);
				pc.sendPackets(new S_SkillSound(pc.getId(), 751));
				pc.broadcastPacket(new S_SkillSound(pc.getId(), 751));
				pc.sendPackets(new S_SkillBrave(pc.getId(), 1, speed_two));
				pc.broadcastPacket(new S_SkillBrave(pc.getId(), 1, 0));
				pc.setBraveSpeed(1);
			}
			if (speed_three > 0) {
				pc.setSkillEffect(STATUS_THIRD_SPEED, speed_three * 1000);
				pc.sendPackets(new S_SkillSound(pc.getId(), 8031));
				pc.broadcastPacket(new S_SkillSound(pc.getId(), 8031));
				pc.sendPackets(new S_Liquor(pc.getId(), 8)); // 人物 * 1.15
				pc.broadcastPacket(new S_Liquor(pc.getId(), 8)); // 人物 * 1.15
				pc.sendPackets(new S_ServerMessage(1065)); // 將發生神秘的奇蹟力量。
			}
		}

		void mrAcDmg(L1PcInstance pc) {
			if (mr > 0 && mr_time > 0) {
				if (pc.hasSkillEffect(IE_MR)) {
					pc.removeSkillEffect(IE_MR);
				}
				pc.addMr(mr);
				pc.setIe_Mr(mr);
				pc.setSkillEffect(IE_MR, mr_time * 1000);
			}
			if (ac > 0 && ac_time > 0) {
				if (pc.hasSkillEffect(IE_AC)) {
					pc.removeSkillEffect(IE_AC);
				}
				pc.addAc(-ac);
				pc.setIe_Ac(ac);
				pc.setSkillEffect(IE_AC, ac_time * 1000);
			}
			if (dmg > 0 && dmg_time > 0) {
				if (pc.hasSkillEffect(IE_DMG)) {
					pc.removeSkillEffect(IE_DMG);
				}
				pc.setIe_Dmg(dmg);
				pc.setSkillEffect(IE_DMG, dmg_time * 1000);
			}
			if (exp_rate > 0 && exp_time > 0) {
				if (pc.hasSkillEffect(IE_EXP)) {
					pc.removeSkillEffect(IE_EXP);
				}
				pc.setIe_Exp(exp_rate);
				pc.setSkillEffect(IE_EXP, exp_time * 1000);
			}
			pc.sendPackets(new S_SPMR(pc));
			pc.sendPackets(new S_OwnCharStatus(pc));
		}

		void poly(L1PcInstance pc) {
			if (poly_id > 0 && poly_time > 0) {
				int awakeSkillId = pc.getAwakeSkillId();
				if ((awakeSkillId == AWAKEN_ANTHARAS)
						|| (awakeSkillId == AWAKEN_FAFURION)
						|| (awakeSkillId == AWAKEN_VALAKAS)) {
					pc.sendPackets(new S_ServerMessage(1384)); // 目前狀態中無法變身。
					return;
				}
				L1PolyMorph.doPoly(pc, poly_id, poly_time,
						L1PolyMorph.MORPH_BY_ITEMMAGIC);
			}
		}

		void gfx(L1PcInstance pc) {
			pc.sendPackets(new S_SkillSound(pc.getId(), gfxId));
			pc.broadcastPacket(new S_SkillSound(pc.getId(), gfxId));
		}
	}
}
